package org.example.demo1.service;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.example.demo1.config.MonitorConfig;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class PrometheusService {

    private final MonitorConfig monitorConfig;
    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;

    public PrometheusService(MonitorConfig monitorConfig) {
        this.monitorConfig = monitorConfig;
        this.restTemplate = new RestTemplate();
        this.objectMapper = new ObjectMapper();
    }

    /**
     * 查询单个时间点的指标值
     */
    public Double queryInstantValue(String query) {
        List<PrometheusQueryResult> results = queryInstant(query);
        if (!results.isEmpty() && results.get(0).getValue() != null) {
            return results.get(0).getValue();
        }
        return null;
    }

    /**
     * 查询即时指标（返回多个结果）
     */
    public List<PrometheusQueryResult> queryInstant(String query) {
        try {
            // 使用 UriComponentsBuilder 来正确处理URL编码
            String url = UriComponentsBuilder.fromHttpUrl(monitorConfig.getPrometheus().getUrl() + "/api/v1/query")
                    .queryParam("query", query)
                    .encode()
                    .toUriString();

            log.debug("Querying Prometheus: {}", url);

            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);

            JsonNode jsonNode = objectMapper.readTree(response.getBody());
            String status = jsonNode.path("status").asText();

            if (!"success".equals(status)) {
                String error = jsonNode.path("error").asText();
                log.error("Prometheus query failed: {}", error);
                return Collections.emptyList();
            }

            JsonNode resultNode = jsonNode.path("data").path("result");
            List<PrometheusQueryResult> results = new ArrayList<>();

            for (JsonNode result : resultNode) {
                PrometheusQueryResult queryResult = new PrometheusQueryResult();

                // 解析metric标签
                JsonNode metricNode = result.path("metric");
                Map<String, String> metric = new HashMap<>();
                metricNode.fields().forEachRemaining(entry ->
                        metric.put(entry.getKey(), entry.getValue().asText())
                );
                queryResult.setMetric(metric);

                // 解析值
                JsonNode valueNode = result.path("value");
                if (valueNode.isArray() && valueNode.size() > 1) {
                    queryResult.setTimestamp(valueNode.get(0).asLong());
                    queryResult.setValue(valueNode.get(1).asDouble());
                }

                results.add(queryResult);
            }

            return results;

        } catch (Exception e) {
            log.error("Failed to query Prometheus instant: {}", query, e);
            return Collections.emptyList();
        }
    }

    /**
     * 查询时间范围内的指标
     */
    public List<PrometheusQueryResult> queryRange(String query, String start, String end, String step) {
        try {
            String url = String.format("%s/api/v1/query_range?query=%s&start=%s&end=%s&step=%s",
                    monitorConfig.getPrometheus().getUrl(), URLEncoder.encode(query, "UTF-8"), start, end, step);

            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            JsonNode jsonNode = objectMapper.readTree(response.getBody());

            List<PrometheusQueryResult> results = new ArrayList<>();
            JsonNode resultNode = jsonNode.path("data").path("result");

            for (JsonNode result : resultNode) {
                PrometheusQueryResult queryResult = new PrometheusQueryResult();

                // 解析metric标签
                JsonNode metricNode = result.path("metric");
                Map<String, String> metric = new HashMap<>();
                metricNode.fields().forEachRemaining(entry ->
                        metric.put(entry.getKey(), entry.getValue().asText())
                );
                queryResult.setMetric(metric);

                // 解析时间序列数据
                JsonNode valuesNode = result.path("values");
                List<TimeSeriesPoint> points = new ArrayList<>();

                for (JsonNode value : valuesNode) {
                    TimeSeriesPoint point = new TimeSeriesPoint();
                    point.setTimestamp(value.get(0).asLong());
                    point.setValue(value.get(1).asDouble());
                    points.add(point);
                }

                queryResult.setValues(points);
                results.add(queryResult);
            }

            return results;
        } catch (Exception e) {
            log.error("Failed to query Prometheus range: {}", query, e);
            return Collections.emptyList();
        }
    }

    /**
     * 获取所有可用的指标名称
     */
    public List<String> getMetricNames() {
        try {
            String url = monitorConfig.getPrometheus().getUrl() + "/api/v1/label/__name__/values";
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);

            JsonNode jsonNode = objectMapper.readTree(response.getBody());
            JsonNode dataNode = jsonNode.path("data");

            List<String> metrics = new ArrayList<>();
            for (JsonNode metric : dataNode) {
                metrics.add(metric.asText());
            }

            return metrics;
        } catch (Exception e) {
            log.error("Failed to get metric names", e);
            return Collections.emptyList();
        }
    }

    /**
     * 检查Prometheus连接状态
     */
    public boolean isHealthy() {
        try {
            String url = monitorConfig.getPrometheus().getUrl() + "/-/healthy";
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            return response.getStatusCode().is2xxSuccessful();
        } catch (Exception e) {
            log.error("Prometheus health check failed", e);
            return false;
        }
    }

    // Prometheus查询结果
    @Data
    public class PrometheusQueryResult {
        private Map<String, String> metric;
        private Long timestamp;
        private Double value;
        private List<TimeSeriesPoint> values; // 用于范围查询
    }

    // 时间序列数据点
    @Data
    public class TimeSeriesPoint {
        private Long timestamp;
        private Double value;
    }
}
